package zero.tech.games.phz.work.sync;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.alibaba.fastjson.JSONObject;

import zero.tech.core.ZeroContext;
import zero.tech.core.data.KeyVal;
import zero.tech.core.util.StringHelper;
import zero.tech.core.work.AynWork;
import zero.tech.core.work.WorkManager;
import zero.tech.games.common.WaterMode;
import zero.tech.games.entity.games.Club;
import zero.tech.games.logic.common.Room;
import zero.tech.games.logic.data.panel.SmallPanel;
import zero.tech.games.logic.service.api.ILogicService;
import zero.tech.games.phz.data.PhzBigPanel;
import zero.tech.games.phz.data.PhzConfig;
import zero.tech.games.phz.data.PhzRoomCache;
import zero.tech.games.phz.data.PhzSmallPanel;
import zero.tech.games.phz.data.entity.PlayerBigCal;
import zero.tech.games.phz.data.entity.PlayerSmallCal;
import zero.tech.games.phz.work.queue.AfterGameOverCalculateQueueWork;
import zero.tech.wsnet.controller.LogicController;

public class GameOverCalculateSyncWork extends AynWork{
	private Room room;
	private int source;
	@Override
	public void init(Object... objs) throws Exception {
		room=(Room) objs[0];
		source=(int) objs[1];
	}

	@Override
	public void run() {
		synchronized (room.getTransform_lock()) {
			bigCalculate(room);
			Club club=room.getClub();
			if(club!=null) {
				//结算代码在此处
				roomTransform(room);
			}else {
				//结算砖石
				diamondTransform(room);
			}
			WorkManager.getManager().submit(AfterGameOverCalculateQueueWork.class,room,source);
		}
	}
	
	

	private void diamondTransform(Room room2) {
		PhzConfig phzConfig = (PhzConfig) room.getGameConfig();
		int water_mode=phzConfig.getWater_mode();
		long water_num=phzConfig.getWater_num();
		Map<Integer,LogicController> controllers=room.getAllControllers();
		Map<Integer,Long> diamondchangemap=new HashMap<>();
		if(water_mode==WaterMode.AA) {
			for(LogicController logicController:controllers.values()) {
				int uid=logicController.getId();
				diamondchangemap.put(uid, -water_num);
			}
		}
		if(!diamondchangemap.isEmpty()) {
			ILogicService logicService=ZeroContext.getInstance(ILogicService.class);
			logicService.gameUpdateDiamondBatch(room, diamondchangemap);
		}		
	}

	private void roomTransform(Room room) {
		PhzConfig phzConfig = (PhzConfig) room.getGameConfig();
		int water_mode=phzConfig.getWater_mode();
		long water_num=phzConfig.getWater_num();
		long free_water_num=phzConfig.getFree_water_num();
		Map<Integer,Long> watermap=new HashMap<>();
		Map<Integer,Long> goldchangemap=new HashMap<>();
		
		Map<Integer,Long> winmap=new HashMap<>();
		Map<Integer,LogicController> controllers=room.getAllControllers();
		List<Integer> uids=new ArrayList<Integer>();
		for(LogicController logicController:controllers.values()) {
			int uid=logicController.getId();
			long gold_from_gate=logicController.getGold_from_gate();
			long gold=logicController.getGold();
			long win=gold-gold_from_gate;
			winmap.put(uid, win);
			uids.add(uid);
		}
		if(water_mode==WaterMode.WINER) {
			//大赢家抽水
			List<KeyVal<Integer, Long>>  list=StringHelper.parseMapToList(winmap);
			Collections.sort(list,new Comparator<KeyVal<Integer, Long>>() {
				@Override
				public int compare(KeyVal<Integer, Long> o1, KeyVal<Integer, Long> o2) {
					return (int) (o2.getV()-o1.getV());
				}
			});
			int bigwinner_uid=list.get(0).getK();
			long win=list.get(0).getV();
			if(win>free_water_num) {
				//超出面抽水限额,需要进行抽水
				watermap.put(bigwinner_uid, water_num);
			}
		}else {
			//AA抽水
			for(LogicController logicController:controllers.values()) {
				int uid=logicController.getId();
				watermap.put(uid, water_num);
			}
		}
		//除去抽水
		for(LogicController logicController:controllers.values()) {
			int uid=logicController.getId();
			long gold_from_gate=logicController.getGold_from_gate();
			long gold=logicController.getGold();
			if(watermap.containsKey(uid)) {
				gold=gold-watermap.get(uid);
			}
			logicController.setGold(gold);
			long change=gold-gold_from_gate;
			goldchangemap.put(uid, change);
		}
		
		if(water_mode==WaterMode.WINER) {
			//计算平分业绩
			long total=0;
			for(Entry<Integer,Long> entry:watermap.entrySet()) {
				total+=entry.getValue();
			}
			watermap.clear();
			long pinjun=total/controllers.size();
			for(LogicController logicController:controllers.values()) {
				watermap.put(logicController.getId(), pinjun);
			}
		}
		
		
		
		String joiners=JSONObject.toJSONString(uids);
		ILogicService logicService=ZeroContext.getInstance(ILogicService.class);
		logicService.gameUpdateBatch(room, joiners, null, goldchangemap, watermap);
	}

	private void bigCalculate(Room room) {
		PhzRoomCache phzRoomCache = (PhzRoomCache) room.getRoomCache();
		PhzConfig phzConfig=(PhzConfig) room.getGameConfig();
		PhzBigPanel phzBigPanel = new PhzBigPanel();
		phzBigPanel.setGameOverTime(System.currentTimeMillis());
		phzRoomCache.setBigPanel(phzBigPanel);
		
		long base_score=phzConfig.getBase_score();
		
		Map<Integer,Integer> hupai_times=phzRoomCache.getHupai_times();//胡牌次数
		Map<Integer,Integer> zimo_times=phzRoomCache.getZimo_times();//自摸次数
		Map<Integer,Integer> dianpao_times=phzRoomCache.getDianpao_times();//点炮次数
		Map<Integer,Integer> tipai_times=phzRoomCache.getTipai_times();//提牌次数
		
		Map<Integer,Integer> total_win_score=new HashMap<>();//赢总胡息
		Map<Integer,Integer> danju_zuigao=new HashMap<>();//单局最高
		for(SmallPanel smallPanel:phzRoomCache.getSmallPanels().values()) {
			PhzSmallPanel pdkSmallPanel = (PhzSmallPanel) smallPanel;
			List<PlayerSmallCal> playerSmallCals=pdkSmallPanel.getPlayerCals();
			for(PlayerSmallCal playerSmallCal:playerSmallCals) {
				int uid=playerSmallCal.getSimpleUser().getUid();
				int cur_win_score=playerSmallCal.getCur_win_score();
				if(cur_win_score!=0) {
					if(!total_win_score.containsKey(uid)) {
						total_win_score.put(uid, cur_win_score);//赢总分
					}else {
						int old=total_win_score.get(uid);
						total_win_score.put(uid, old+cur_win_score);
					}
					
					if(!danju_zuigao.containsKey(uid)) {
						danju_zuigao.put(uid,cur_win_score);
					}else {
						int old=danju_zuigao.get(uid);
						if(cur_win_score>old) {
							danju_zuigao.put(uid, cur_win_score);
						}
					}
				}
				
			}
		}
		int num=room.getAllControllers().size();
		Map<Integer,Integer> map=new HashMap<>();
		List<KeyVal<Integer, Integer>> list=new ArrayList<>();
		for(LogicController logicController:room.getAllControllers().values()) {
			int uid=logicController.getId();
			int hupai_count=hupai_times.get(uid)==null?0:hupai_times.get(uid);
			int zimo_count=zimo_times.get(uid)==null?0:zimo_times.get(uid);
			int dianpao_count=dianpao_times.get(uid)==null?0:dianpao_times.get(uid);
			int tipai_count=tipai_times.get(uid)==null?0:tipai_times.get(uid);
			
			int huxi_score=total_win_score.get(uid)==null?0:total_win_score.get(uid);
			
			list.add(new KeyVal<Integer, Integer>(uid, huxi_score));
			
			int danjuzuigao=danju_zuigao.get(uid)==null?0:danju_zuigao.get(uid);
			
			PlayerBigCal playerBigCal=new PlayerBigCal();
			playerBigCal.setSimpleUser(logicController.getSimpleUser());
			playerBigCal.setHuxi_total(huxi_score);
			playerBigCal.setHupai_times(hupai_count);
			playerBigCal.setZimo_times(zimo_count);
			playerBigCal.setDianpao_times(dianpao_count);
			playerBigCal.setTipai_times(tipai_count);
			playerBigCal.setDanju_max_score(danjuzuigao);
			playerBigCal.setLeft_gold(logicController.getGold());
			phzBigPanel.getPlayerCals().add(playerBigCal);
			
		}
		
		Map<Integer, Integer> bird_win_score=new HashMap<>();
		Collections.sort(list,new Comparator<KeyVal<Integer, Integer>>() {
			@Override
			public int compare(KeyVal<Integer, Integer> o1, KeyVal<Integer, Integer> o2) {
				return o2.getV()-o1.getV();
			}
		});
		Map<Integer,Integer> birds=phzRoomCache.getBirds();
		if(num==2) {
			//2人局
			KeyVal<Integer, Integer> one=list.get(0);
			KeyVal<Integer, Integer> two=list.get(1);
			int first_win=one.getV()-two.getV();
			int second_win=two.getV()-one.getV();
			if(one.getV()==two.getV()) {
				//2人分数一样
				bird_win_score.put(one.getK(), 0);
				bird_win_score.put(two.getK(), 0);
			}else {
				int bird_first=birds.get(one.getK())==null?0:birds.get(one.getK());
				int bird_second=birds.get(two.getK())==null?0:birds.get(two.getK());
				bird_win_score.put(one.getK(), bird_first+bird_second);
				bird_win_score.put(two.getK(), -(bird_first+bird_second));
				first_win+=bird_first+bird_second;
				second_win=second_win-(bird_first+bird_second);
			}
			map.put(one.getK(), first_win);
			map.put(two.getK(), second_win);
		}else if(num==3) {
			//3人局
			KeyVal<Integer, Integer> one=list.get(0);
			KeyVal<Integer, Integer> two=list.get(1);
			KeyVal<Integer, Integer> three=list.get(2);
			
			
			int first_win_second=one.getV()-two.getV();
			int first_win_three=one.getV()-three.getV();
			int first_win=first_win_second+first_win_three;
			
			int second_win_first=two.getV()-one.getV();
			int second_win_three=two.getV()-three.getV();
			int second_win=second_win_first+second_win_three;
			
			int three_win_first=three.getV()-one.getV();
			int three_win_second=three.getV()-two.getV();
			int three_win=three_win_first+three_win_second;
			
			if(one.getV()==two.getV()) {
				if(two.getV()==three.getV()) {
					bird_win_score.put(one.getK(), 0);
					bird_win_score.put(two.getK(), 0);
					bird_win_score.put(three.getK(), 0);
				}else {
					int bird_first=birds.get(one.getK())==null?0:birds.get(one.getK());
					int bird_second=birds.get(two.getK())==null?0:birds.get(two.getK());
					int bird_three=birds.get(three.getK()==null?0:birds.get(three.getK()));
					bird_win_score.put(one.getK(), bird_first+bird_three);
					bird_win_score.put(two.getK(), bird_second+bird_three);
					bird_win_score.put(two.getK(), -((bird_first+bird_three)+(bird_second+bird_three)));
					
					first_win+=bird_first+bird_three;
					second_win+=bird_second+bird_three;
					three_win-=((bird_first+bird_three)+(bird_second+bird_three));
				}
				
			}else {
				int bird_first=birds.get(one.getK())==null?0:birds.get(one.getK());
				int bird_second=birds.get(two.getK())==null?0:birds.get(two.getK());
				int bird_three=birds.get(three.getK())==null?0:birds.get(three.getK());
				
				first_win+=(bird_first+bird_second)+(bird_first+bird_three);
				second_win-=(bird_first+bird_second);
				three_win-=(bird_first+bird_three);
			}
			
			map.put(one.getK(),first_win);
			map.put(two.getK(),second_win);
			map.put(three.getK(),three_win);
		}
		
		
		for(PlayerBigCal playerBigCal:phzBigPanel.getPlayerCals()) {
			int uid=playerBigCal.getSimpleUser().getUid();
			int win=map.get(uid);
			int bird_win=bird_win_score.get(uid);
			playerBigCal.setTotal_win_score(win);
			playerBigCal.setBird_win_score(bird_win);
			
			long total_win_gold=win*base_score;
			LogicController logicController = room.getAllControllers().get(uid);
			long old_gold=logicController.getGold();
			long old_win=logicController.getWin();
			long win_gold=total_win_gold;
			logicController.setWin(old_win+win_gold);
			logicController.setGold(old_gold+win_gold);
		}
		
	}

}
